/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2010 huliqing, huliqing.cn@gmail.com
 *
 * This file is part of QFaces.
 * QFaces is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QFaces is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with QFaces.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 这个文件是QFaces的一部分。
 * 您可以单独使用或分发这个文件，但请不要移除这个头部声明信息.
 * QFaces是一个自由软件，您可以自由分发、修改其中的源代码或者重新发布它，
 * 新的任何修改后的重新发布版必须同样在遵守LGPL3或更后续的版本协议下发布.
 * 关于LGPL协议的细则请参考COPYING、COPYING.LESSER文件，
 * 您可以在QFaces的相关目录中获得LGPL协议的副本，
 * 如果没有找到，请连接到 http://www.gnu.org/licenses/ 查看并获取副本。
 *
 * - Author: Huliqing
 * - Contact: huliqing.cn@gmail.com
 * - License: GNU Lesser General Public License (LGPL)
 * - Blog and source code availability: http://www.huliqing.name/
 */

Q.F.UIGraphValidator = {
	init : function(ID_CLIENT, ID_FULL, ID_INPUT, ID_GRAPH_ZONE, ID_MESSAGE_ZONE, ID_NEXT, ID_VALIDATE_CODE, 
			state, componentClass, width, height, fontName, fontPath, fontSize, 
			offsetX, offsetY, space, message, messageCorrect, messageError, lazy, ignoreCase, renderNextButton, disableAjax, distort, diverse, renderListenerExp,
			styleClass, styleClassCorrect, styleClassError) {
		var ui = new Q.F.UIGraphValidator.GraphValidator(ID_CLIENT, ID_FULL, ID_INPUT, ID_GRAPH_ZONE, ID_MESSAGE_ZONE, ID_NEXT, ID_VALIDATE_CODE,
				state, componentClass, width, height, fontName, fontPath, fontSize, 
				offsetX, offsetY, space, message, messageCorrect, messageError, lazy, ignoreCase, renderNextButton, disableAjax, distort, diverse, renderListenerExp,
				styleClass, styleClassCorrect, styleClassError);
		Q.F.put(ID_CLIENT, ui);
	}
}
Q.F.UIGraphValidator.GraphValidator = function (ID_CLIENT, ID_FULL, ID_INPUT, ID_GRAPH_ZONE, ID_MESSAGE_ZONE, ID_NEXT, ID_VALIDATE_CODE,
		state, componentClass, width, height, fontName, fontPath, fontSize, 
		offsetX, offsetY, space, message, messageCorrect, messageError, lazy, ignoreCase, renderNextButton, disableAjax, distort, diverse, renderListenerExp,
		styleClass, styleClassCorrect, styleClassError) {
	this.ID_CLIENT = ID_CLIENT;
	this.ID_FULL = ID_FULL;
	this.ID_VALIDATE_CODE = ID_VALIDATE_CODE;
	this.input = Q.get(ID_INPUT);
	this.graphZone = Q.get(ID_GRAPH_ZONE);
	this.messageZone = Q.get(ID_MESSAGE_ZONE);
	this.nextObj = null;
	this.state = parseInt(state, 10);
	this.componentClass = componentClass;
	this.width = width;
	this.height = height;
	this.fontName = fontName;
	this.fontPath = fontPath;
	this.fontSize = fontSize;
	this.offsetX = offsetX;
	this.offsetY = offsetY;
	this.space = space;
	this.message = message;
	this.messageCorrect = messageCorrect;
	this.messageError = messageError;
	this.lazy = (lazy == "true");
	this.ignoreCase = (ignoreCase == "true");
	this.renderNextButton = (renderNextButton == "true");
	this.disableAjax = (disableAjax == "true");
	this.distort = distort;
	this.diverse = diverse;
	this.renderListenerExp = renderListenerExp;
	this.styleClass = styleClass;
	this.styleClassCorrect = styleClassCorrect;
	this.styleClassError = styleClassError;
	
	this.img = null; // 图片文件
	this.hasDraw = false; // 表示是否已经生成过图形
	this.lastValue = null;// input最后一次被验证的字符
	
	// ---- Interface
	
	// 生成下一张图片
	this.next = function() {
		this.draw(true);
	}

	// ---- Init 
	
	this.init = function() {
		Q.debug("GraphValidator init, state=" + this.state);
		var _self = this;
		if (this.renderNextButton) {
			this.nextObj = Q.get(ID_NEXT);
			this.nextObj.onclick = function() {
				_self.next();
			}
		}
		// state == 0表示首次渲染（非回传,即无提交form）
		if (this.state == 0) {
			if (this.lazy) {
				this.input.onfocus = function() {
					_self.firstDraw();
				}
			} else {
				this.draw(true);
			}
		} else {
			// state == -1 or state == -1, draw(false) false参数表示不产生新的code
			// 经过验证错误或正确时不需要重新产生code
			// 如：验证错误后，重新产生图形，但是不改变code,这样便于用户重新填写code.
			// 验证正确也不需要产生新code,否则每次重新渲染页面时用户都必须重新填写code.
			this.draw(false);
		}
		// 如果没有关闭ajax验证,则添加事件响应
		if (!this.disableAjax) {
			this.input.onblur = function() {
				_self.validate();
			}
		}
		this.updateState(this.state);
	}
	this.validate = function() {
		if (!this.isValidate())
			return;
		this.messageZone.innerHTML = "";
		this.messageZone.appendChild(Q.F.getLoading());
		var _self = this;
		var ajax = Q.F.Ajax.build(this.ID_CLIENT);
		ajax.put("componentClass", this.componentClass)
		.put("validateCodeId", this.ID_VALIDATE_CODE)
		.put("code", this.input.value)
		.put("ignoreCase", this.ignoreCase);
		var process = function() {
			Q.F.loading(false);
			var result = (ajax.request.responseText == "true");
			_self.updateState(result ? 1 : -1);
			_self.lastValue = _self.input.value; // 保存最后一次验证的值
		}
		ajax.setProcess(process);
		ajax.get();
	}
	this.isValidate = function() {
		return (this.input.value != this.lastValue);
	}
	this.updateState = function(state) {
		Q.debug("update state, state=" + state);
		this.state = state;
		switch (state) {
		case -1:
			this.messageZone.innerHTML = this.messageError;
			this.messageZone.className = this.styleClassError;
			break;
		case 0:
			this.messageZone.innerHTML = this.message;
			this.messageZone.className = this.styleClass;
			break;
		case 1:
			this.messageZone.innerHTML = this.messageCorrect;
			this.messageZone.className = this.styleClassCorrect;
			break;
		}
	}
	// 首次生成图形
	this.firstDraw = function() {
		if (!this.hasDraw)
			this.draw(true);
	}
	// 生成图形，reCreate标识是否重新产生验证码
	this.draw = function(reCreate) {
		Q.debug("draw, renderListenerExp=" + this.renderListenerExp);
		this.hasDraw = true;
		this.lastValue = null; // 清null,以保证isValidate方法正确返回必要结果
		var filter = Q.F.Filter.build();
		filter
		.put("validateCodeId", this.ID_VALIDATE_CODE)
		.put("viewId", Q.F.viewId)
		.put("componentClass", this.componentClass)
		.put("renderListenerExp", this.renderListenerExp)
		.put("width", this.width)
		.put("height", this.height)
		.put("fontName", this.fontName)
		.put("fontPath", this.fontPath)
		.put("fontSize", this.fontSize)
		.put("offsetX", this.offsetX)
		.put("offsetY", this.offsetY)
		.put("space", this.space)
		.put("distort", this.distort)
		.put("diverse", this.diverse)
		// reCreate 标识是否需要产生一个新的Code,必要的
		.put("create", (reCreate ? "true" : "fasle"))
		// 加入一个时间用于防止浏览器缓存
		.put("temp", new Date().getTime());
		
		var _self = this;
		if (this.img == null) {
			this.img = document.createElement("img");
			this.img.setAttribute("alt", "Waiting...");
			if (this.renderNextButton)
				this.img.setAttribute("title", this.nextObj.innerHTML);
			this.img.onclick = function() {
				_self.next();
			}
			this.img.style.cursor = "pointer";
			this.graphZone.appendChild(this.img);
		}
		this.img.setAttribute("src", filter.getResult());
	}
	this.init();
}